﻿using BUGCOME.Model;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace BUGCOME.Repository
{
    /// <summary>
    /// 基于SqlSugar的异步仓储接口
    /// 提供通用的数据访问异步操作
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    public interface IBaseRepository<T> : ISimpleClient<T> where T : class, new()
    {
        #region 添加操作（异步版本）

        /// <summary>
        /// 异步添加单个实体
        /// </summary>
        /// <param name="t">要添加的实体</param>
        /// <param name="ignoreNull">是否忽略空值</param>
        /// <returns>受影响的行数</returns>
        Task<long> AddAsync(T t, bool ignoreNull = true);

        /// <summary>
        /// 异步批量插入实体
        /// </summary>
        /// <param name="t">实体列表</param>
        /// <returns>受影响的行数</returns>
        Task<long> InsertAsync(List<T> t);

        /// <summary>
        /// 异步插入实体并指定插入列
        /// </summary>
        /// <param name="parm">要插入的实体</param>
        /// <param name="iClumns">要插入的列表达式</param>
        /// <param name="ignoreNull">是否忽略空值</param>
        /// <returns>受影响的行数</returns>
        Task<int> InsertAsync(T parm, Expression<Func<T, object>> iClumns = null, bool ignoreNull = true);

        /// <summary>
        /// 获取异步插入构建器
        /// </summary>
        /// <param name="t">要插入的实体</param>
        /// <returns>插入构建器</returns>
        IInsertable<T> Insertable(T t);

        #endregion 添加操作

        #region 更新操作（异步版本）

        /// <summary>
        /// 异步更新实体
        /// </summary>
        /// <param name="entity">要更新的实体</param>
        /// <param name="ignoreNullColumns">是否忽略空列</param>
        /// <param name="data">更新的数据</param>
        /// <returns>受影响的行数</returns>
        Task<long> UpdateAsync(T entity, bool ignoreNullColumns = false, object data = null);

        /// <summary>
        /// 只更新表达式指定的列（异步）
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <param name="expression">要更新的列表达式</param>
        /// <param name="ignoreAllNull">是否忽略所有空值</param>
        /// <returns>受影响的行数</returns>
        Task<long> UpdateAsync(T entity, Expression<Func<T, object>> expression, bool ignoreAllNull = false);

        /// <summary>
        /// 带条件的异步更新
        /// </summary>
        /// <param name="entity">实体对象</param>
        /// <param name="expression">要更新的列表达式</param>
        /// <param name="where">更新条件</param>
        /// <returns>受影响的行数</returns>
        Task<long> UpdateAsync(T entity, Expression<Func<T, object>> expression, Expression<Func<T, bool>> where);

        /// <summary>
        /// 表达式方式异步更新
        /// </summary>
        /// <param name="where">更新条件</param>
        /// <param name="columns">要更新的列</param>
        /// <returns>受影响的行数</returns>
        Task<long> UpdateAsync(Expression<Func<T, bool>> where, Expression<Func<T, T>> columns);

        #endregion 更新操作

        #region 事务操作

        DbResult<bool> UseTran(ISqlSugarClient client, Action action);

        bool UseTran2(Action action);

        #endregion 事务操作

        #region 删除操作（异步版本）

        /// <summary>
        /// 获取异步删除构建器
        /// </summary>
        /// <returns>删除构建器</returns>
        IDeleteable<T> Deleteable();

        /// <summary>
        /// 异步删除指定ID的实体
        /// </summary>
        /// <param name="id">实体ID</param>
        /// <param name="title">操作标题</param>
        /// <returns>受影响的行数</returns>
        Task<long> DeleteAsync(object id, string title = "");

        /// <summary>
        /// 异步删除表中所有数据
        /// </summary>
        /// <returns>受影响的行数</returns>
        Task<long> DeleteTableAsync();

        /// <summary>
        /// 异步 truncate 表（清空表）
        /// </summary>
        /// <returns>是否成功</returns>
        Task<bool> TruncateAsync();

        #endregion 删除操作

        #region 查询操作（异步版本）

        /// <summary>
        /// 异步根据条件查询分页数据
        /// </summary>
        /// <param name="where">查询条件</param>
        /// <param name="parm">分页参数</param>
        /// <returns>分页结果</returns>
        Task<PagedInfo<T>> GetPagesAsync(Expression<Func<T, bool>> where, PagerInfo parm);

        /// <summary>
        /// 带排序的异步分页查询
        /// </summary>
        /// <param name="where">查询条件</param>
        /// <param name="parm">分页参数</param>
        /// <param name="order">排序表达式</param>
        /// <param name="orderEnum">排序类型</param>
        /// <returns>分页结果</returns>
        Task<PagedInfo<T>> GetPagesAsync(Expression<Func<T, bool>> where, PagerInfo parm,
                                        Expression<Func<T, object>> order, OrderByType orderEnum = OrderByType.Asc);

        /// <summary>
        /// 带自定义排序的异步分页查询
        /// </summary>
        /// <param name="where">查询条件</param>
        /// <param name="parm">分页参数</param>
        /// <param name="order">排序表达式</param>
        /// <param name="orderByType">排序类型字符串</param>
        /// <returns>分页结果</returns>
        Task<PagedInfo<T>> GetPagesAsync(Expression<Func<T, bool>> where, PagerInfo parm,
                                        Expression<Func<T, object>> order, string orderByType);

        /// <summary>
        /// 异步判断是否存在符合条件的记录
        /// </summary>
        /// <param name="expression">查询条件</param>
        /// <returns>是否存在</returns>
        Task<bool> AnyAsync(Expression<Func<T, bool>> expression);

        /// <summary>
        /// 获取异步查询构建器
        /// </summary>
        /// <returns>查询构建器</returns>
        ISugarQueryable<T> Queryable();

        /// <summary>
        /// 异步获取所有记录
        /// </summary>
        /// <param name="useCache">是否使用缓存</param>
        /// <param name="cacheSecond">缓存时间(秒)</param>
        /// <returns>实体列表</returns>
        Task<List<T>> GetAllAsync(bool useCache = false, int cacheSecond = 3600);

        /// <summary>
        /// 异步执行SQL查询并转换为列表
        /// </summary>
        /// <param name="sql">SQL语句</param>
        /// <param name="obj">参数对象</param>
        /// <returns>查询结果列表</returns>
        Task<List<T>> SqlQueryToListAsync(string sql, object obj = null);

        /// <summary>
        /// 异步根据ID获取实体
        /// </summary>
        /// <param name="pkValue">主键值</param>
        /// <returns>实体对象</returns>
        Task<T> GetIdAsync(object pkValue);

        #endregion 查询操作

        #region 存储过程操作（异步版本）

        /// <summary>
        /// 异步执行存储过程并返回DataTable
        /// </summary>
        /// <param name="procedureName">存储过程名称</param>
        /// <param name="parameters">参数列表</param>
        /// <returns>查询结果DataTable</returns>
        Task<DataTable> UseStoredProcedureToDataTableAsync(string procedureName, List<SugarParameter> parameters);

        /// <summary>
        /// 异步执行存储过程并返回带输出参数的元组
        /// </summary>
        /// <param name="procedureName">存储过程名称</param>
        /// <param name="parameters">参数列表</param>
        /// <returns>包含DataTable和输出参数的元组</returns>
        Task<(DataTable, List<SugarParameter>)> UseStoredProcedureToTupleAsync(string procedureName, List<SugarParameter> parameters);

        #endregion 存储过程操作
    }
}